/*
 * MIT License
 * 
 * Copyright (c) 2017 wen.gu <454727014@qq.com>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

 /***************************************************************************
 * Name: tiny_list.h
 *
 * Purpose: tiny list data structure and API
 *
 * Developer:
 *   wen.gu , 2016-09-14
 *
 * TODO: 
 *
 ***************************************************************************/

#ifndef __TINY_LIST_H__
#define __TINY_LIST_H__


#include "general_type.h"


#ifdef __cplusplus
extern "C" {
#endif

/***************************************************************************
 *
 * macro declaration
 *
 ***************************************************************************/

/***************************************************************************
 *
 * data structure declaration
 *
 ***************************************************************************/
/**@brief list node, 
 *@note sub node need put the flow structure in the start position of sub node. 
 */
typedef struct tiny_list_node_s
{
    struct tiny_list_node_s* next; /**< pointer to next node */
}tiny_list_node_t;

/** callback function for free list node */
typedef void (*TinyListNodeFreeFunc_t)(void* node);

/** the data structure of list */
typedef struct tiny_list_s 
{
    GU32 node_count; /**< how many node in current list */
	TinyListNodeFreeFunc_t node_free; /**< callback function for free list node */
    tiny_list_node_t* head; /**< list header node */
	tiny_list_node_t* tail; /**< list tail node */
}tiny_list_t;

/***************************************************************************
 *
 * API declaration
 *
 ***************************************************************************/

/**
 *@brief  initialize list
 *
 *@param  tl         [io] pointer to the structure of tiny_list_t
 *@param  node_free  [in] the callback function for free list node.
 *
 *@return none.
 *@see
 *
 */
G_API void tfListInitialize(tiny_list_t* tl, TinyListNodeFreeFunc_t node_free);

/**
 *@brief  get first node
 *
 *@param  tl [in] pointer to the structure of tiny_list_t
 *
 *@return success: first node in list, fail: NULL.
 *@see
 *
 */
G_API tiny_list_node_t* tfListFront(tiny_list_t* tl);

/**
 *@brief  pop first node from list
 *
 *@param  tl [in] pointer to the structure of tiny_list_t
 *
 *@return none
 *@see
 *@note if node_free != NULL, then this operation will free the popped node.
 *
 */
G_API void tfListPopFront(tiny_list_t* tl);

/**
 *@brief  push a node to the front of list
 *
 *@param  tl   [in] pointer to the structure of tiny_list_t
 *@param  node [in] pointer to new node
 *
 *@return none.
 *@see
 *
 */
G_API void tfListPushFront(tiny_list_t* tl, tiny_list_node_t* node);

/**
 *@brief  push a node to the back of list
 *
 *@param  tl   [in] pointer to the structure of tiny_list_t
 *@param  node [in] pointer to new node
 *
 *@return none.
 *@see
 *
 */
G_API void tfListPushBack(tiny_list_t* tl, tiny_list_node_t* node);

/**
 *@brief  remove a node from list(with prev node)
 *
 *@param  tl   [in] pointer to the structure of tiny_list_t
 *@param  prev [in] pointer to the prev node of current node.
 *@param  node [in] pointer to the node which need to removed
 *
 *@return none.
 *@see
 *@note  prev will not removed. prev cann't be NULL.  
 *
 */
G_API void tfListRemoveFast(tiny_list_t* tl,tiny_list_node_t* prev, tiny_list_node_t* node);

/**
 *@brief  insert a node to list(with prev node)
 *
 *@param  tl   [in] pointer to the structure of tiny_list_t
 *@param  prev [in] pointer to the prev node of current node.
 *@param  node [in] pointer to the node which need to insert
 *
 *@return none.
 *@see
 *@note if prev == NULL, then insert node to the head of list.  
 *
 */
G_API void tfListInsertFast(tiny_list_t* tl,tiny_list_node_t* prev, tiny_list_node_t* node);

/**
 *@brief  clear(remove and free) all of node in list 
 *
 *@param  tl [in] pointer to the structure of tiny_list_t
 *
 *@return none.
 *@see
 *@note if node_free != NULL, then this operation will free all node
 *
 */
G_API void tfListClear(tiny_list_t* tl);

/**
 *@brief  how many node in list
 *
 *@param  tl [in] pointer to the structure of tiny_list_t
 *
 *@return the count of node in current list.
 *@see
 *
 */
G_API GU32 tfListCount(tiny_list_t* tl);

/**
 *@brief  check is current empty?
 *
 *@param  tl [in] pointer to the structure of tiny_list_t
 *
 *@return empty: GTRUE, not: GFALSE
 *@see
 *
 */
G_API GBOL tfListIsEmpty(tiny_list_t* tl);


#ifdef __cplusplus
}
#endif

#endif //end of __TINY_LIST_H__
